// 云函数入口文件
const cloud = require("wx-server-sdk");
const https = require("https");
const axios = require("axios");

const cheerio = require("cheerio");
const iconv = require("iconv-lite");

cloud.init();

function br2n(str) {
  return str.replace(
    /(<br\s?\/?>|\n)+((\s+\n+)|(\s+<br\s?\/?>+)|\n+|<br\s?\/?>+)*/gi,
    "\n\n"
  );
}

async function getResult(
  result,
  $,
  _selector,
  __read_url,
  slice,
  pageIndex,
  pageSize
) {
  const data = {};
  for (const key in result) {
    const rule = result[key];
    let selector = _selector || $(rule.selector);
    // console.log(key, rule)
    if (rule.type == "function") {
      // 函数执行
      data[key] = selector[rule.function]();
    } else if (rule.type == "selector") {
      rule.selector_handle.forEach(handle => {
        if (handle.type == "function") {
          if (handle.args !== undefined) {
            selector = selector[handle.function](handle.args);
          } else {
            selector = selector[handle.function]();
          }
        }
      });
      if (rule.attr) {
        data[key] = selector.attr(rule.attr);
      } else {
        data[key] = selector;
      }
    } else if (rule.type == "array") {
      let arr = [];
      if (rule.offset) {
        selector = selector.slice(rule.offset);
      }
      for (let index = 0; index < selector.length; index++) {
        const item = selector[index];
        if (slice) {
          if (
            index >= (pageIndex - 1) * pageSize &&
            index < pageIndex * pageSize
          ) {
            if (rule.result) {
              const result = await getResult(
                rule.result,
                $,
                $(item),
                __read_url
              );
              arr.push(result);
            } else {
              arr.push($(item).attr(rule.attr));
            }
          }
        } else {
          if (rule.result) {
            const result = await getResult(rule.result, $, $(item), __read_url);
            arr.push(result);
          } else {
            arr.push($(item).attr(rule.attr));
          }
        }
      }
      data[key] = arr;
    } else if (rule.type == "worm") {
      const html = selector.html();
      const firstIndex = html.indexOf(rule.worm_handle.first);
      const lastIndex = html.indexOf(rule.worm_handle.last);
      let url = html.substring(firstIndex, lastIndex);
      if (rule.baseUrl) {
        url = rule.baseUrl + url;
      }
      const res = await axios({
        url,
        responseType: "json",
        httpsAgent: new https.Agent({
          keepAlive: true,
          rejectUnauthorized: false
        })
      });
      if (res.status == 200) {
        data[key] = res.data.info;
      } else {
        data[key] = "转码失败";
      }
    } else {
      data[key] = selector.attr(rule.attr);
    }
    if (rule.baseUrl == "__read_url") {
      data[key] = __read_url + (data[key] == "./" ? "" : data[key]);
    } else if (rule.baseUrl == "__last") {
      console.log(__read_url);
      const index = __read_url.lastIndexOf("/");
      data[key] =
        __read_url.substr(0, index + 1) + (data[key] == "./" ? "" : data[key]);
    } else if (rule.baseUrl) {
      data[key] = rule.baseUrl + data[key];
    }
    if (rule.br2n) {
      // console.log(data[key]);
      data[key] = br2n(data[key]);
      if (rule.tag2s) {
        rule.tag2s.forEach(tag => {
          if (typeof tag == "string") {
            data[key] = data[key].replace(
              new RegExp(
                "[\\s↵]*<" + tag + ">[\\s\\S]*<\\/" + tag + ">[\\s↵]*",
                "gi"
              ),
              ""
            );
          } else {
            data[key] = data[key].replace(
              new RegExp(
                "[\\s↵]*<" +
                  tag.start +
                  ">[\\s\\S]*<\\/" +
                  tag.end +
                  ">[\\s↵]*",
                "gi"
              ),
              ""
            );
          }
        });
      }
      // console.log(data[key])
    }
  }
  // console.log(data)
  return data;
}

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext();

  cloud.updateConfig({
    env: wxContext.ENV == "local" ? "test-go5gy" : wxContext.ENV
  });

  const {
    url,
    method = "get",
    postData = {},
    result,
    type = "utf8",
    slice = false,
    pageIndex = 1,
    pageSize = 6
  } = event;

  // console.log({
  //   url,
  //   method,
  //   responseType: type == "utf8" ? "text" : "arraybuffer",
  // })

  const res = await axios({
    url,
    method,
    data: postData,
    responseType: type == "utf8" ? "text" : "arraybuffer",
    httpsAgent: new https.Agent({
      keepAlive: true,
      rejectUnauthorized: false
    })
  });
  if (res.status == 200) {
    let html = res.data;
    if (type != "utf8") {
      html = iconv.decode(html, type);
    }
    const $ = cheerio.load(html, {
      decodeEntities: false
    });
    // console.log(html)
    const data = await getResult(
      result,
      $,
      undefined,
      url,
      slice,
      pageIndex,
      pageSize
    );
    // console.log('data:', data)
    return data;
  } else {
    console.error();
  }
};
